﻿using GalaSoft.MvvmLight.Command;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;

using System;
using System.IO;

using System.Windows.Shapes;
using System.Windows.Threading;
using 安检系统.Model;
using 安检系统.Utils;
using 安检系统.ViewModel;
using ModuleTech;
using ModuleTech.Gen2;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.TextBox;
using System.Security.Policy;

namespace 安检系统
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        private SynchronizationContext _syncContext = null;

        private DispatcherTimer timer;
        private MainViewModel mainViewModel;

        private delegate void MyDelegate(Object value);

        private List<String> carList;

        /// <summary>
        /// 连接状态
        /// </summary>
        public bool bConnState = false;

        public bool bConnState2 = false;

        /// <summary>
        /// 端口句柄
        /// </summary>
        public IntPtr pHandle = IntPtr.Zero;

        public IntPtr pHandle2 = IntPtr.Zero;
        public string sReaderIP = App.GetBaseInfo().RFID_sReaderIP;
        public string sReaderIP2 = App.GetBaseInfo().RFID_sReaderIP2;
        private int iReaderPoint = int.Parse(App.GetBaseInfo().RFID_iReaderPoint);
        private int iReaderPoint2 = int.Parse(App.GetBaseInfo().RFID_iReaderPoint2);
        public string RFIDCode = "";
        public string RFIDCode2 = "";
        public int RFIDReadCount = 0;
        public DateTime recordTime = DateTime.Now;
        public DateTime recordTime2 = DateTime.Now;
        private System.Timers.Timer rfidTimer1;
        private System.Timers.Timer rfidTimer2;

        private SerialCache cache1 = new SerialCache(capacity: 5);
        private SerialCache cache2 = new SerialCache(capacity: 5);

        private readonly Dictionary<string, DateTime> _recent1 = new Dictionary<string, DateTime>();     // —— 去重缓存：记录 EPC 最近一次出现的时间 —— //
        private readonly Dictionary<string, DateTime> _recent2 = new Dictionary<string, DateTime>();     // —— 去重缓存：记录 EPC 最近一次出现的时间 —— //
        private readonly TimeSpan _dedupTtl = TimeSpan.FromSeconds(2);  // 去重时间窗，默认 2 秒（可按需调整）
        private readonly TimeSpan _dedupTt2 = TimeSpan.FromSeconds(2);  // 去重时间窗，默认 2 秒（可按需调整）
        private string RfidReader = App.GetBaseInfo().RfidReader;

        private Reader rdr1;
        private Reader rdr2;

        /// <summary>
        /// 读卡状态
        /// </summary>
        private bool bReadCodeState = false;

        private bool bReadCodeState2 = false;

        /// <summary>
        /// 读取卡信息的线程
        /// </summary>
        private Thread readThread = null;

        private Thread readThread2 = null;
        private String queryStatus = "0";

        private System.Windows.Forms.PictureBox m_pictureBoxHik;

        public MainWindow()
        {
            InitializeComponent();
            _syncContext = SynchronizationContext.Current;
            carList = new List<String>();
            m_pictureBoxHik = new System.Windows.Forms.PictureBox();
            videoHostHik.Child = m_pictureBoxHik;

            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromSeconds(1);
            timer.Tick += new EventHandler(timeCycle);
            timer.Start();
            mainViewModel = new MainViewModel();
            this.DataContext = mainViewModel;
            //this.DataContext=viewModel;

            this.Loaded += Window_Loaded;
            this.Unloaded += Window_UnLoaded;
            this.Closed += Window_Closed;

            m_bInitSDK = CHCNetSDK.NET_DVR_Init();
            if (m_bInitSDK == false)
            {
                MessageBox.Show("NET_DVR_Init error!");
                return;
            }
        }

        private void Window_UnLoaded(object sender, RoutedEventArgs e)
        {
            if (null != timer && timer.IsEnabled)
            {
                timer.Stop();
            }
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            if (rfidTimer1 != null) rfidTimer1.Stop();
            if (rfidTimer2 != null) rfidTimer2.Stop();
            if ("2".Equals(RfidReader))
            {
                try { rdr1?.StopReading(); } catch { }
                try { rdr1?.Disconnect(); } catch { }
                try { rdr2?.StopReading(); } catch { }
                try { rdr2?.Disconnect(); } catch { }
            }
        }

        public void timeCycle(object sender, EventArgs e)
        {
            new Thread(() =>
            {
                Application.Current.Dispatcher.BeginInvoke(
                    new Action(() =>
                    {
                        Timer1.Text = DateTime.Now.ToString();
                    }));
            }).Start();
        }

        public void doDataRefresh(object sender, RoutedEventArgs e)
        {
            LoadData();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            txtCurLoginUser.Text = "操作员: " + App.getGlobalVariables().LoginUserName;

            if ("1".Equals(RfidReader))//老RFID读卡设备
            {
                bool bInit = false;
                bInit = RfidApi.SAAT_TCPInit(out pHandle, sReaderIP, iReaderPoint);//RFID iP端口    pHandle为句柄，初始化读卡器
                if (!bInit)
                {
                    MessageBox.Show("RFID初始化失败");
                    //_syncContext.Post(AddLogMessage, new LogInfo("RFID初始化失败", true));
                }
                bool bInit2 = false;
                bInit2 = RfidApi.SAAT_TCPInit(out pHandle2, sReaderIP2, iReaderPoint2);//RFID iP端口    pHandle为句柄，初始化读卡器
                if (!bInit2)
                {
                    MessageBox.Show("RFID2初始化失败");
                    //_syncContext.Post(AddLogMessage, new LogInfo("RFID初始化失败", true));
                }
                // 2.打开连接
                bConnState = RfidApi.SAAT_Open(pHandle);//根据句柄打开读卡器，返回true和false
                if (!bConnState)
                {
                    MessageBox.Show("RFID连接读卡器失败");
                    //_syncContext.Post(AddLogMessage, new LogInfo("RFID连接读卡器失败", true));
                }
                bConnState2 = RfidApi.SAAT_Open(pHandle2);//根据句柄打开读卡器，返回true和false
                if (!bConnState2)
                {
                    MessageBox.Show("RFID2连接读卡器失败");
                    //_syncContext.Post(AddLogMessage, new LogInfo("RFID连接读卡器失败", true));
                }

                if (bInit && bConnState)
                {
                    this.beginReadRFID(new JObject());
                }
                if (bInit2 && bConnState2)
                {
                    this.beginReadRFID2(new JObject());
                }
            }
            else if ("2".Equals(RfidReader))//网络RFID设备
            {
                var region = ModuleTech.Region.PRC;
                int antsnum = 1;//天线数量
                try
                {
                    rdr1 = Reader.Create(sReaderIP + ":" + iReaderPoint, region, antsnum);
                }
                catch (Exception ex)
                {
                    rdr1 = null; // 标记为空，避免后续误用
                    Console.WriteLine($"RFID1 连接失败: {ex.Message}");
                }

                try
                {
                    rdr2 = Reader.Create(sReaderIP2 + ":" + iReaderPoint2, region, antsnum);
                }
                catch (Exception ex)
                {
                    rdr2 = null; // 标记为空，避免后续误用
                    Console.WriteLine($"RFID2 连接失败: {ex.Message}");
                }

                if (rdr1 != null)
                {
                    setRfidConfig(rdr1);

                    // 订阅回调 + 开始盘存（关键：之后不再调用 Read(500)）
                    rdr1.TagsRead += Rdr_TagsRead1;// rdr.TagsRead读写器 SDK 提供的一个事件（event）,.当读写器在异步盘存模式下识别到标签时，就会自动触发这个事件。
                    rdr1.StartReading();
                }
                if (rdr2 != null)
                {
                    setRfidConfig(rdr2);

                    rdr2.TagsRead += Rdr_TagsRead2;// rdr.TagsRead读写器 SDK 提供的一个事件（event）,.当读写器在异步盘存模式下识别到标签时，就会自动触发这个事件。
                    rdr2.StartReading();
                }
            }

            LoadData();
            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromSeconds(App.GetBaseInfo().RefreshSeconds);
            timer.Tick += new EventHandler(timeCycle1);
            timer.Start();

            String hikVideo_url = App.GetBaseInfo().HikVideo_URL;
            if (hikVideo_url != null && !"".Equals(hikVideo_url))
            {
                HikVideo_Open();
                btnPreview_Click();
            }
        }

        /// <summary>
        /// 新网络RFID设备读取卡号
        /// </summary>
        /// <param name="sender">
        /// </param>
        /// <param name="e">
        /// </param>
        private void Rdr_TagsRead1(object sender, Reader.TagsReadEventArgs e)
        {
            foreach (var tag in e.Tags)
            {
                string epc = tag.EPCString;
                if (string.IsNullOrWhiteSpace(epc)) continue;

                var now = DateTime.Now;

                // —— 去重：2 秒内相同 EPC 不重复显示 —— //
                if (_recent1.TryGetValue(epc, out var last))
                {
                    if ((now - last) < _dedupTtl)
                        continue; // 丢弃重复
                }
                _recent1[epc] = now;
                MessageBox.Show(epc);
                _ = Task.Run(() => getMsgByRfidCode(epc));
            }
        }

        /// <summary>
        /// 新网络RFID设备读取卡号
        /// </summary>
        /// <param name="sender">
        /// </param>
        /// <param name="e">
        /// </param>
        private void Rdr_TagsRead2(object sender, Reader.TagsReadEventArgs e)
        {
            foreach (var tag in e.Tags)
            {
                string epc = tag.EPCString;
                if (string.IsNullOrWhiteSpace(epc)) continue;

                var now = DateTime.Now;

                // —— 去重：2 秒内相同 EPC 不重复显示 —— //
                if (_recent2.TryGetValue(epc, out var last))
                {
                    if ((now - last) < _dedupTt2)
                        continue; // 丢弃重复
                }
                _recent2[epc] = now;

                _ = Task.Run(() => getMsgByRfidCode2(epc));
            }
        }

        /// <summary>
        /// 设置RFID配置
        /// </summary>
        /// <param name="rdr">
        /// </param>
        private void setRfidConfig(Reader rdr)
        {
            try
            {
                ushort power = 3000;
                // 频段请按你的设备/地区设置（中国大陆通常用 PRC；你之前用 NA 可能读不到）
                var region = ModuleTech.Region.PRC;
                rdr.ParamSet("Region", region);
                int antsnum = 1;//天线数量
                // 天线功率（单位：0.01 dBm），如 3000 = 30 dBm
                var antPowers = new AntPower[antsnum];
                for (byte i = 0; i < antsnum; i++)
                    antPowers[i] = new AntPower((byte)(i + 1), power, power);
                rdr.ParamSet("AntPowerConf", antPowers); //配置天线功率。

                // 读计划（GEN2 + 指定天线）
                int[] useants = new int[antsnum];
                for (int i = 0; i < antsnum; i++) useants[i] = i + 1;
                rdr.ParamSet("ReadPlan", new SimpleReadPlan(TagProtocol.GEN2, useants));//设置盘存计划，定义“用哪些天线、用什么协议去盘存标签”。

                // —— 3) 异步盘存（设备主动推送到回调） —— //
                var bro = new BackReadOption
                {
                    IsFastRead = true, // 连续快速盘存
                    FRTMetadata = new BackReadOption.FastReadTagMetaData
                    {
                        IsAntennaID = true,
                        IsRSSI = true,
                        IsReadCnt = true,
                        IsTimestamp = true
                    }
                };
                rdr.ParamSet("BackReadOption", bro);//作用：配置异步盘存的细节，比如快速模式、附带哪些元数据。
            }
            catch (Exception ex)
            {
                MessageBox.Show("启动失败：" + ex.Message);
            }
        }

        private void timeCycle1(object sender, EventArgs e)
        {
            LoadData();
        }

        private void DealMessage(object jsonStr)
        {
            mainViewModel.Count01 = 0;
            mainViewModel.Count02 = 0;
            try
            {
                JObject jsonObj = JObject.Parse((string)jsonStr);
                bool success = (bool)jsonObj.GetValue("success");
                if (!success) return;
                JArray json = (JArray)jsonObj.GetValue("data");
                //List<Record> records = JsonConvert.DeserializeObject<List<Record>>(json);

                mainViewModel.RecordList.Clear();
                mainViewModel.item1.Clear();
                mainViewModel.item2.Clear();
                mainViewModel.Count01 = 0;

                foreach (JObject record in json)
                {
                    ItemViewModel itemViewModel = new ItemViewModel();
                    itemViewModel.CarNumber = (String)record.GetValue("carNumber");
                    itemViewModel.id = (String)record.GetValue("id");
                    itemViewModel.carEffluentStandard = (String)record.GetValue("carEffluentStandard");

                    String checkStatus = (String)record.GetValue("checkStatus") + "";
                    if (checkStatus.Equals("0"))
                    {
                        mainViewModel.Count01 = mainViewModel.Count01 + 1;
                        mainViewModel.item1.Add(itemViewModel);
                    }
                }
            }
            catch (Exception ex) { }
        }

        public ItemViewModel getRecordByJSON(JObject item)
        {
            ItemViewModel itemViewModel = new ItemViewModel();
            itemViewModel.CarNumber = (String)item.GetValue("carNumber");
            return itemViewModel;
        }

        public void LoadData()
        {
            mainViewModel.queryParam.carNumber = carNumber.Text.Trim();
            //mainViewModel.queryParam.queryStatus = queryStatus;
            //mainViewModel.queryParam.isIncludeLeave = ((bool)cbIncludeLeave.IsChecked) ?"1":"0";
            mainViewModel.queryParam.timeRange = App.GetBaseInfo().TimeRange;
            new Task(() =>
            {
                Invoke();
            }).Start();
        }

        public async void Invoke()
        {
            try
            {
                JObject paramJSON1 = new JObject();
                String ip = App.GetBaseInfo().HttpServerIp;
                String port = App.GetBaseInfo().HttpServerPort;

                try
                {
                    string param = JObject.FromObject(mainViewModel.queryParam).ToString();
                    var response = HttpPostHelper.doHttpAsyncPost("/parkRecord/list", param);
                    String msg = await response;
                    JObject jsonObj = JObject.Parse(msg);
                    bool success = (bool)jsonObj.GetValue("success");
                    if (!success) return;
                    var jsonStr = jsonObj["data"].ToString();
                    List<Record> records = JsonConvert.DeserializeObject<List<Record>>(jsonStr);

                    _syncContext.Post(SetDataList, records);

                    try
                    {
                        JObject paramJSON = new JObject();
                        paramJSON.Add("type", "2");
                        ip = App.GetBaseInfo().HttpServerIp;
                        port = App.GetBaseInfo().HttpServerPort;

                        String responses = HttpPostHelper.doHttpPost("http://" + ip + ":" + port + "/ytBillLineUp/queryList", paramJSON.ToString());
                        JObject respJson = JObject.Parse(responses);
                        bool successes = (bool)respJson["success"];
                        if (successes)
                        {
                            var jsonStrs = respJson["data"].ToString();
                            List<Car> carRecords = JsonConvert.DeserializeObject<List<Car>>(jsonStrs);
                            _syncContext.Post(SetDataLists, carRecords);
                        }
                    }
                    catch (Exception ex)
                    {
                    }
                }
                catch (Exception ex)
                {
                }
            }
            catch (Exception ex) { }
        }

        private void SetDataLists(object obj)
        {
            mainViewModel.item3.Clear();
            if (null == obj) return;
            List<Car> records = (List<Car>)obj;

            foreach (Car record in records)
            {
                mainViewModel.item3.Add(record);
            }
        }

        private void SetDataList(object obj)
        {
            mainViewModel.RecordList.Clear();

            if (null == obj) return;
            List<Record> records = (List<Record>)obj;

            foreach (Record record in records)
            {
                if (record.checkStatus.Equals("0"))
                {
                    if (carList != null && carList.Count() > 0)
                    {
                        if (carList[0].Equals("0"))
                        {
                            record.carNumberColor = "Blcak";
                            record.Visibility = "Visible";
                        }
                        else
                        {
                            if (!carList.Contains(record.carNumber))
                            {
                                record.carNumberColor = "Red";
                                record.Visibility = "Hidden";
                            }
                            else
                            {
                                record.carNumberColor = "Blcak";
                                record.Visibility = "Visible";
                            }
                        }
                    }
                    else
                    {
                        record.carNumberColor = "Black";
                        record.Visibility = "Visible";
                    }
                }
                else
                {
                    record.Visibility = "Hidden";
                    record.carNumberColor = "Blcak";
                }

                if (null == record.carEffluentStandard || "".Equals(record.carEffluentStandard))
                {
                    record.StandardEdit = "Visible";
                    record.StandardBackgroundColor = "Red";
                    record.StandardForegroundColor = "White";
                    record.StandardText = "Hidden";
                }
                else
                {
                    record.StandardEdit = "Hidden";
                    record.StandardBackgroundColor = "Transparent";
                    record.StandardForegroundColor = "Black";
                    record.StandardText = "Visible";
                }

                mainViewModel.RecordList.Add(record);
            }
        }

        private void Button_Click_QueryByCarNumber(object sender, RoutedEventArgs e)

        {
            LoadData();
        }

        private void Button_Click_Check(object sender, RoutedEventArgs e)
        {
            Record selectedRecord = (Record)RecordList.SelectedItem;
            ShowCheckWindow(selectedRecord);
        }

        private void ShowCheckWindow(object obj)
        {
            Record record = (Record)obj;
            CheckWindow checkWindow = new CheckWindow();
            JObject jsonObj = new JObject();
            jsonObj.Add("carno", record.carNumber);
            jsonObj.Add("id", record.id);
            checkWindow.setParam(jsonObj.ToString());
            checkWindow.Owner = this;
            bool result = (bool)checkWindow.ShowDialog();
            if (result)
            {
                LoadData();
            }
        }

        /*        private void beginReadRFID(Object obj)
                {
                    // 开启Timer更新接收的信息
                    if (readThread != null)
                    {
                        if (readThread.IsAlive)
                        {
                            readThread.Abort();
                            readThread.Join();
                        }
                    }
                    if (!CReadCode()) //发送读卡命令失败
                    {
                        MessageBox.Show("发送读卡命令失败!");
                        //_syncContext.Post(AddLogMessage, new LogInfo("RFID发送读卡命令失败", true));
                        return;
                    }
                    bReadCodeState = true;
                    readThread = new Thread(new ThreadStart(RevCodeMsgThread));
                    readThread.Start();
                }

                private void beginReadRFID2(Object obj)
                {
                    bReadCodeState2 = false;
                    // 开启Timer更新接收的信息
                    *//*  if (readThread2 != null)
                      {
                          if (readThread2.IsAlive)
                          {
                              readThread2.Abort();
                              readThread2.Join();
                          }
                      }*//*
                    if (readThread2 != null && readThread2.IsAlive)
                    {
                        readThread2.Join();
                    }

                    if (!CReadCode2()) //发送读卡命令失败
                    {
                        MessageBox.Show("发送读卡命令失败!");
                        //_syncContext.Post(AddLogMessage, new LogInfo("RFID发送读卡命令失败", true));
                        return;
                    }
                    bReadCodeState2 = true;
                    readThread2 = new Thread(new ThreadStart(RevCodeMsgThread2));
                    readThread2.IsBackground = true;
                    readThread2.Start();
                }
          测试注释 */

        private void beginReadRFID(object obj)
        {
            if (!CReadCode())
            {
                MessageBox.Show("发送读卡命令失败!");
                return;
            }

            string RfidRepeatedTime = App.GetBaseInfo().RfidRepeatedTime;
            double time;
            bool success = double.TryParse(RfidRepeatedTime, out time);
            if (!success)
            {
                MessageBox.Show("Rfid读取频率格式设置错误");
            }

            recordTime = DateTime.MinValue;

            rfidTimer1 = new System.Timers.Timer(time);
            rfidTimer1.Elapsed += RfidTimer1_Elapsed;
            rfidTimer1.AutoReset = true;
            rfidTimer1.Start();
        }

        private void beginReadRFID2(object obj)
        {
            if (!CReadCode2())
            {
                MessageBox.Show("发送读卡命令失败!");
                return;
            }

            recordTime2 = DateTime.MinValue;
            string RfidRepeatedTime = App.GetBaseInfo().RfidRepeatedTime;
            double time;
            bool success = double.TryParse(RfidRepeatedTime, out time);
            if (!success)
            {
                MessageBox.Show("Rfid读取频率格式设置错误");
            }
            rfidTimer2 = new System.Timers.Timer(time);
            rfidTimer2.Elapsed += RfidTimer2_Elapsed;
            rfidTimer2.AutoReset = true;
            rfidTimer2.Start();
        }

        private void RfidTimer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            RevMsgStruct revMsg = new RevMsgStruct();
            if (CRevCodeMsg(pHandle, ref revMsg) == 1)//读卡
            {
                LogToFile(DateTime.Now + "---------" + revMsg.sCodeData);
                if (cache1.Contains(revMsg.sCodeData))  // 判断 5 秒内是否存在
                {
                    // Console.WriteLine($"卡 {card} 已存在(5秒内)，拦截，不开闸。");
                }
                else
                {
                    cache1.Insert(revMsg.sCodeData);   // 插入到缓存
                    _syncContext.Post(getMsgByRfidCode, revMsg.sCodeData);
                }
            }
        }

        private readonly string baseFolderPath = @"C:\date";  // 根目录

        public void LogToFile(string logContent)
        {
            try
            {
                // 当前时间
                DateTime now = DateTime.Now;

                // 确保目录存在
                if (!Directory.Exists(baseFolderPath))
                {
                    Directory.CreateDirectory(baseFolderPath);
                }

                // 文件名格式：yyyyMMdd_HH.log，例如 20250826_09.log
                string fileName = $"{now:yyyyMMdd_HH}.log";
                string filePath = System.IO.Path.Combine(baseFolderPath, fileName);

                // 使用 StreamWriter 以追加方式写入
                using (StreamWriter writer = new StreamWriter(filePath, true))
                {
                    writer.WriteLine($"[{now:yyyy-MM-dd HH:mm:ss}] {logContent}");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error writing to file: {ex.Message}");
            }
        }

        private void RfidTimer2_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            RevMsgStruct revMsg = new RevMsgStruct();
            if (CRevCodeMsg(pHandle2, ref revMsg) == 1)
            {
                LogToFile(DateTime.Now + "---------" + revMsg.sCodeData);
                if (cache2.Contains(revMsg.sCodeData))  // 判断 5 秒内是否存在
                {
                    // Console.WriteLine($"卡 {card} 已存在(5秒内)，拦截，不开闸。");
                }
                else
                {
                    cache2.Insert(revMsg.sCodeData);   // 插入到缓存
                    _syncContext.Post(getMsgByRfidCode2, revMsg.sCodeData);
                }
            }
        }

        /// <summary>
        /// 天线号
        /// </summary>
        private byte sAntenna = 1;

        /// <summary>
        /// 读卡次数，单次，循环
        /// </summary>
        private int SAAT_READ_TYPE = 1;

        public bool CReadCode()
        {
            byte SAAT_SCAN_TRIES = 3;

            return RfidApi.SAAT_6CReadEPCCode(pHandle, sAntenna, (byte)SAAT_READ_TYPE, SAAT_SCAN_TRIES);//读取卡片pHandle句柄，nAntenna天线号，nType操作模式
        }

        public bool CReadCode2()
        {
            byte SAAT_SCAN_TRIES = 3;

            return RfidApi.SAAT_6CReadEPCCode(pHandle2, sAntenna, (byte)SAAT_READ_TYPE, SAAT_SCAN_TRIES);//读取卡片pHandle句柄，nAntenna天线号，nType操作模式
        }

        public int CRevCodeMsg(IntPtr handle, ref RevMsgStruct revMsg)
        {
            byte sLength = 255;     //
            string sData = "";
            byte[] btData = new byte[255];
            int bResult = 0;

            try
            {
                bResult = RfidApi.SAAT_6CRevEPCMsg(handle, out sAntenna, btData, out sLength);
            }
            catch { }

            if (bResult == 1 && sLength != 255)
            {
                revMsg.nAntenna = (int)sAntenna;
                for (byte bytei = 0; bytei < sLength; bytei++)
                    sData += btData[bytei].ToString("X2");
                revMsg.sCodeData = sData;
                revMsg.nRepeatTime = 1;
                revMsg.tBeginTime = System.DateTime.Now;
                revMsg.tLastTime = System.DateTime.Now;
            }
            return bResult;
        }

        public void getMsgByRfidCode(object obj)
        {
            String rfidCode = (String)obj;

            try
            {
                JObject bodyJson = new JObject();
                bodyJson.Add("rfidCode", rfidCode);

                String result = HttpPostHelper.doHttpPost("/bdDocCar/findListByRfidCode", bodyJson.ToString());
                JObject jsonObj = JObject.Parse(result);
                bool success = (bool)jsonObj.GetValue("success");
                LogToFile(DateTime.Now + "---------1" + jsonObj.ToString());
                if (success)
                {
                    String comm = App.GetBaseInfo().IO_Com_PortName;
                    String inOpenPort = App.GetBaseInfo().IO_In_Open_Port;
                    PortControlHelper.openDoor1(comm, int.Parse(inOpenPort));//控制道闸
                    LogToFile(DateTime.Now + "---------1道闸抬起");
                    var jsonStr = jsonObj["data"].ToString();
                    Car car = JsonConvert.DeserializeObject<Car>(jsonStr);
                    if (null == car) return;
                    Car rfidCar = car;
                    addRecord(rfidCar);
                }
            }
            catch (Exception ex)
            {
                //MessageBox.Show(ex.ToString());
            }
            //}).Start();
        }

        public void getMsgByRfidCode2(object obj)
        {
            String rfidCode = (String)obj;
            //new Task(() =>
            //{
            try
            {
                JObject bodyJson = new JObject();
                bodyJson.Add("rfidCode", rfidCode);

                String result = HttpPostHelper.doHttpPost("/bdDocCar/findListByRfidCode", bodyJson.ToString());
                JObject jsonObj = JObject.Parse(result);
                LogToFile(DateTime.Now + "---------2" + jsonObj.ToString());
                bool success = (bool)jsonObj.GetValue("success");
                if (success)
                {
                    String comm = App.GetBaseInfo().IO_Com_PortName2;
                    String inOpenPort = App.GetBaseInfo().IO_In_Open_Port2;

                    PortControlHelper.openDoor2(comm, int.Parse(inOpenPort));//控制道闸
                    LogToFile(DateTime.Now + "---------2道闸抬起");
                    var jsonStr = jsonObj["data"].ToString();
                    Car car = JsonConvert.DeserializeObject<Car>(jsonStr);
                    if (null == car) return;
                    Car rfidCar = car;
                    addRecord(rfidCar);
                }
            }
            catch (Exception ex)
            {
                //MessageBox.Show(ex.ToString());
            }
            //}).Start();
        }

        public void addRecord(Car rfidCar)
        {
            try
            {
                JObject paramJSON = new JObject();
                paramJSON.Add("carNumber", rfidCar.carNo);
                String response = HttpPostHelper.doHttpPost("http://192.168.19.220:8000/busParkRecord/add", paramJSON.ToString());
                JObject respJson = JObject.Parse(response);
                bool success = (bool)respJson["success"];
                if (success)
                {
                    _syncContext.Post(reload, "");
                }
            }
            catch (Exception ex)
            {
                //MessageBox.Show("系统错误,请联系管理员");
            }
        }

        private void reload(object state)
        {
            LoadData();
        }

        private void changeStatus(object sender, RoutedEventArgs e)
        {
            RadioButton btn = (RadioButton)sender;
            String queryStatus = (String)btn.Tag;
            mainViewModel.queryParam.queryStatus = queryStatus;
            LoadData();
        }

        private void Button_Add_Record(object sender, RoutedEventArgs e)
        {
            RecordWindow recordWindow = new RecordWindow();
            recordWindow.Owner = this;
            bool result = (bool)recordWindow.ShowDialog();
            if (result)
            {
                LoadData();
            }
        }

        private void Button_Open_Gate(object sender, RoutedEventArgs e)
        {
            String inOpenPort = App.GetBaseInfo().IO_In_Open_Port;

            Task.Run(() =>
            {
                PortControlHelper.openDoor1(App.GetBaseInfo().IO_Com_PortName, int.Parse(inOpenPort));
            });
        }

        private void Button_Close_Gate(object sender, RoutedEventArgs e)
        {
            String inClosePort = App.GetBaseInfo().IO_In_Close_Port;
            Task.Run(() =>
            {
                PortControlHelper.openDoor1(App.GetBaseInfo().IO_Com_PortName, int.Parse(inClosePort));
            });
        }

        private void Button_Click_EditStandard(object sender, RoutedEventArgs e)
        {
            Record record = (Record)RecordList.SelectedItem;
            StandardWindow standardWindow = new StandardWindow();
            standardWindow.Owner = this;
            standardWindow.carNumber = record.carNumber;
            standardWindow.recordId = record.id;
            standardWindow.vehiclecode = record.VehicleCode;
            standardWindow.pickerTime = record.RegistrationTime;
            standardWindow.Num = record.Num;
            bool result = (bool)standardWindow.ShowDialog();
            if (result)
            {
                LoadData();
            }
        }

        private void Button_Click_CarIcon(object sender, MouseButtonEventArgs e)
        {
            Border border = (Border)sender;
            ItemViewModel itemViewModel = (ItemViewModel)border.Tag;

            String standard = itemViewModel.carEffluentStandard;
            if (null == standard || "".Equals(standard))
            {
                StandardWindow standardWindow = new StandardWindow();
                standardWindow.Owner = this;
                standardWindow.carNumber = itemViewModel.CarNumber;
                standardWindow.recordId = itemViewModel.id;
                bool result = (bool)standardWindow.ShowDialog();
                if (result)
                {
                    LoadData();
                }
                return;
            }
            CheckWindow checkWindow = new CheckWindow();
            JObject jsonObj = new JObject();
            jsonObj.Add("carno", itemViewModel.CarNumber);
            jsonObj.Add("id", itemViewModel.id);
            checkWindow.setParam(jsonObj.ToString());
            checkWindow.Owner = this;
            if ((bool)checkWindow.ShowDialog())
            {
                LoadData();
            }
        }

        private uint iLastErr = 0;
        private Int32 m_lUserID = -1;
        private bool m_bInitSDK = false;
        private bool m_bRecord = false;
        private bool m_bTalk = false;
        private Int32 m_lRealHandle = -1;
        private int lVoiceComHandle = -1;
        private string str;

        private CHCNetSDK.REALDATACALLBACK RealData = null;
        private CHCNetSDK.LOGINRESULTCALLBACK LoginCallBack = null;
        public CHCNetSDK.NET_DVR_PTZPOS m_struPtzCfg;
        public CHCNetSDK.NET_DVR_USER_LOGIN_INFO struLogInfo;
        public CHCNetSDK.NET_DVR_DEVICEINFO_V40 DeviceInfo;

        private void HikVideo_Open()
        {
            if (m_lUserID < 0)
            {
                struLogInfo = new CHCNetSDK.NET_DVR_USER_LOGIN_INFO();

                //设备IP地址或者域名
                byte[] byIP = System.Text.Encoding.Default.GetBytes(App.GetBaseInfo().HikVideo_URL);
                struLogInfo.sDeviceAddress = new byte[129];
                byIP.CopyTo(struLogInfo.sDeviceAddress, 0);

                //设备用户名
                byte[] byUserName = System.Text.Encoding.Default.GetBytes(App.GetBaseInfo().HikVideo_Username);
                struLogInfo.sUserName = new byte[64];
                byUserName.CopyTo(struLogInfo.sUserName, 0);

                //设备密码
                byte[] byPassword = System.Text.Encoding.Default.GetBytes(App.GetBaseInfo().HikVideo_Password);
                struLogInfo.sPassword = new byte[64];
                byPassword.CopyTo(struLogInfo.sPassword, 0);

                struLogInfo.wPort = ushort.Parse(App.GetBaseInfo().HikVideo_Port);//设备服务端口号

                if (LoginCallBack == null)
                {
                    LoginCallBack = new CHCNetSDK.LOGINRESULTCALLBACK(cbLoginCallBack);//注册回调函数
                }
                struLogInfo.cbLoginResult = LoginCallBack;
                struLogInfo.bUseAsynLogin = false; //是否异步登录：0- 否，1- 是

                DeviceInfo = new CHCNetSDK.NET_DVR_DEVICEINFO_V40();

                //登录设备 Login the device
                m_lUserID = CHCNetSDK.NET_DVR_Login_V40(ref struLogInfo, ref DeviceInfo);
                if (m_lUserID < 0)
                {
                    iLastErr = CHCNetSDK.NET_DVR_GetLastError();
                    str = "NET_DVR_Login_V40 failed, error code= " + iLastErr; //登录失败，输出错误号
                    MessageBox.Show(str);
                    return;
                }
                else
                {
                    //登录成功
                    //MessageBox.Show("Login Success!");
                    //btnLogin.Text = "Logout";
                }
            }
            else
            {
                //注销登录 Logout the device
                if (m_lRealHandle >= 0)
                {
                    MessageBox.Show("Please stop live view firstly");
                    return;
                }

                if (!CHCNetSDK.NET_DVR_Logout(m_lUserID))
                {
                    iLastErr = CHCNetSDK.NET_DVR_GetLastError();
                    str = "NET_DVR_Logout failed, error code= " + iLastErr;
                    MessageBox.Show(str);
                    return;
                }
                m_lUserID = -1;
                //btnLogin.Text = "Login";
            }
            return;
        }

        public void cbLoginCallBack(int lUserID, int dwResult, IntPtr lpDeviceInfo, IntPtr pUser)
        {
            string strLoginCallBack = "登录设备，lUserID：" + lUserID + "，dwResult：" + dwResult;

            if (dwResult == 0)
            {
                uint iErrCode = CHCNetSDK.NET_DVR_GetLastError();
                strLoginCallBack = strLoginCallBack + "，错误号:" + iErrCode;
            }

            //下面代码注释掉也会崩溃
            if (true)
            {
                object[] paras = new object[2];
                paras[0] = strLoginCallBack;
                paras[1] = lpDeviceInfo;
                //labelLogin.BeginInvoke(new UpdateTextStatusCallback(UpdateClientList), paras);
            }
            else
            {
                //创建该控件的主线程直接更新信息列表
                //UpdateClientList(strLoginCallBack, lpDeviceInfo);
            }
        }

        private void btnPreview_Click()
        {
            if (m_lRealHandle < 0)
            {
                CHCNetSDK.NET_DVR_PREVIEWINFO lpPreviewInfo = new CHCNetSDK.NET_DVR_PREVIEWINFO();
                lpPreviewInfo.hPlayWnd = m_pictureBoxHik.Handle;//预览窗口
                lpPreviewInfo.lChannel = Int16.Parse("1");//预te览的设备通道
                lpPreviewInfo.dwStreamType = 0;//码流类型：0-主码流，1-子码流，2-码流3，3-码流4，以此类推
                lpPreviewInfo.dwLinkMode = 0;//连接方式：0- TCP方式，1- UDP方式，2- 多播方式，3- RTP方式，4-RTP/RTSP，5-RSTP/HTTP
                lpPreviewInfo.bBlocked = true; //0- 非阻塞取流，1- 阻塞取流
                lpPreviewInfo.dwDisplayBufNum = 1; //播放库播放缓冲区最大缓冲帧数
                lpPreviewInfo.byProtoType = 0;
                lpPreviewInfo.byPreviewMode = 0;

                //if (textBoxID.Text != "")
                //{
                //    lpPreviewInfo.lChannel = -1;
                //    byte[] byStreamID = System.Text.Encoding.Default.GetBytes(textBoxID.Text);
                //    lpPreviewInfo.byStreamID = new byte[32];
                //    byStreamID.CopyTo(lpPreviewInfo.byStreamID, 0);
                //}

                if (RealData == null)
                {
                    RealData = new CHCNetSDK.REALDATACALLBACK(RealDataCallBack);//预览实时流回调函数
                }

                IntPtr pUser = new IntPtr();//用户数据

                //打开预览 Start live view
                m_lRealHandle = CHCNetSDK.NET_DVR_RealPlay_V40(m_lUserID, ref lpPreviewInfo, null/*RealData*/, pUser);
                if (m_lRealHandle < 0)
                {
                    iLastErr = CHCNetSDK.NET_DVR_GetLastError();
                    str = "NET_DVR_RealPlay_V40 failed, error code= " + iLastErr; //预览失败，输出错误号
                    MessageBox.Show(str);
                    return;
                }
                else
                {
                    //预览成功
                    //btnPreview.Text = "Stop Live View";
                }
            }
            else
            {
                //停止预览 Stop live view
                if (!CHCNetSDK.NET_DVR_StopRealPlay(m_lRealHandle))
                {
                    iLastErr = CHCNetSDK.NET_DVR_GetLastError();
                    str = "NET_DVR_StopRealPlay failed, error code= " + iLastErr;
                    MessageBox.Show(str);
                    return;
                }
                m_lRealHandle = -1;
                //btnPreview.Text = "Live View";
            }
            return;
        }

        public void RealDataCallBack(Int32 lRealHandle, UInt32 dwDataType, IntPtr pBuffer, UInt32 dwBufSize, IntPtr pUser)
        {
            if (dwBufSize > 0)
            {
                byte[] sData = new byte[dwBufSize];
                Marshal.Copy(pBuffer, sData, 0, (Int32)dwBufSize);

                string str = "实时流数据.ps";
                FileStream fs = new FileStream(str, FileMode.Create);
                int iLen = (int)dwBufSize;
                fs.Write(sData, 0, iLen);
                fs.Close();
            }
        }

        private void Button_GoDiaoduRecord(object sender, RoutedEventArgs e)
        {
            DispatchRecord recordWindow = new DispatchRecord();
            recordWindow.Owner = this;
            bool result = (bool)recordWindow.ShowDialog();
            if (result)
            {
                LoadData();
            }
        }

        private void test_add(object sender, RoutedEventArgs e)
        {
            String rfidcode = "C1C9484D393839373036363237383139";
            _syncContext.Post(getMsgByRfidCode, rfidcode);
        }

        private void test(object sender, RoutedEventArgs e)
        {
            Car car = new Car();
            car.carNo = "鲁E11111";
            addRecord(car);
        }

        private void Button_Close_Gate2(object sender, RoutedEventArgs e)
        {
            String inClosePort = App.GetBaseInfo().IO_In_Close_Port2;

            // 使用后台线程避免卡死 UI
            Task.Run(() =>
            {
                PortControlHelper.openDoor2(App.GetBaseInfo().IO_Com_PortName2, int.Parse(inClosePort));
            });
        }

        private void Button_Open_Gate2(object sender, RoutedEventArgs e)
        {
            String inOpenPort = App.GetBaseInfo().IO_In_Open_Port2;

            Task.Run(() =>
            {
                PortControlHelper.openDoor2(App.GetBaseInfo().IO_Com_PortName2, int.Parse(inOpenPort));
            });
        }

        private void Button_Open_Out(object sender, RoutedEventArgs e)
        {
            String inOpenPort = App.GetBaseInfo().IO_In_Open_PortOut;
            Task.Run(() =>
            {
                PortControlHelper.openDoorOut(App.GetBaseInfo().IO_Com_PortNameOut, int.Parse(inOpenPort));
            });
        }

        private void Button_Close_Out(object sender, RoutedEventArgs e)
        {
            String inClosePort = App.GetBaseInfo().IO_In_Close_PortOut;
            Task.Run(() =>
            {
                PortControlHelper.openDoorOut(App.GetBaseInfo().IO_Com_PortNameOut, int.Parse(inClosePort));
            });
        }
    }
}